//
//  UIScrollView+PullToRefresh.m
//  JiMeiUnv
//
//  Created by devp on 14-9-9.
//  Copyright (c) 2014年 nd. All rights reserved.
//

#import "UIScrollView+PullToRefresh.h"

#import "NDRefreshLoadMoreContainView.h"

#import "JRSwizzle.h"
#import <objc/runtime.h>

#define UITableViewPullToRefreshAssertMainThread()	\
do {	\
NSAssert2([NSThread isMainThread], @"%@->%@方法必须运行在主线程", self, NSStringFromSelector(_cmd));	\
} while (0);
static char nd_UIScrollViewPullToRefresh;
static char nd_UIScrollViewPullToLoadMore;

@implementation UIScrollView (PullToRefresh)

+ (void)load {
    BOOL result = [self jr_swizzleMethod:@selector(willRemoveSubview:) withMethod:@selector(willRemoveSubviewHack:) error:nil];
    result &= [self jr_swizzleMethod:@selector(didAddSubview:) withMethod:@selector(didAddSubviewHack:) error:nil];
    if (!result) {
    }
}

#pragma mark - getter & setter
- (void)setRefreshControl:(NDRefreshControl *)pullToRefreshView {
    [self willChangeValueForKey:@"nd_UIScrollViewPullToRefresh"];
    objc_setAssociatedObject(self, &nd_UIScrollViewPullToRefresh,
                             pullToRefreshView,
                             OBJC_ASSOCIATION_ASSIGN);
    [self didChangeValueForKey:@"nd_UIScrollViewPullToRefresh"];
}

- (NDRefreshControl *)refreshControl {
    return objc_getAssociatedObject(self, &nd_UIScrollViewPullToRefresh);
}

- (void)setLoadMoreControl:(NDRefreshControl *)loadMoreControl {
    [self willChangeValueForKey:@"nd_UIScrollViewPullToLoadMore"];
    objc_setAssociatedObject(self, &nd_UIScrollViewPullToLoadMore,
                             loadMoreControl,
                             OBJC_ASSOCIATION_ASSIGN);
    [self didChangeValueForKey:@"nd_UIScrollViewPullToLoadMore"];
}

- (NDRefreshControl *)loadMoreControl {
    return objc_getAssociatedObject(self, &nd_UIScrollViewPullToLoadMore);
}

- (void)nd_addPullToRefreshWithActionHandler:(void (^)(id sender))refreshActionHandler loadMoreWithActionHandler:(void (^)(id sender))loadMoreActionHandler {
    [self nd_addPullToRefreshWithActionHandler:refreshActionHandler];
    [self nd_addPullToLoadMoreWithActionHandler:loadMoreActionHandler];
}

#pragma mark - overwritten
- (void)willRemoveSubviewHack:(UIView *)subview {
    [self willRemoveSubviewHack:subview];
    if ([subview isKindOfClass:[NDRefreshControl class]]) {
        [self removeObserverForRefreshControl:(NDRefreshControl *)subview];
    }
}

- (void)didAddSubviewHack:(UIView *)subview {
    [self didAddSubviewHack:subview];
    
    if ([subview isKindOfClass:[NDRefreshControl class]]) {
        [self addObserverForRefreshControl:(NDRefreshControl *)subview];
    }
}

#pragma mark - private
- (void)addObserverForRefreshControl:(NDRefreshControl *)refreshControl {
    
    @try {
        //[self removeObserverForRefreshControl:refreshControl];
    }
    @catch (NSException *exception) {
    }
    @finally {
        [self addObserver:refreshControl forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
        [self addObserver:refreshControl forKeyPath:@"pan.state" options:NSKeyValueObservingOptionNew context:nil];
        [self addObserver:refreshControl forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
    }
}

- (void)removeObserverForRefreshControl:(NDRefreshControl *)refreshControl {
    @try {
        [self removeObserver:refreshControl forKeyPath:@"contentOffset"];
        [self removeObserver:refreshControl forKeyPath:@"pan.state"];
        [self removeObserver:refreshControl forKeyPath:@"contentSize"];
    }
    @catch (NSException *exception) {
    }
}

#pragma mark - public
- (void)nd_addPullToRefreshWithActionHandler:(void (^)(id sender))refreshActionHandler {
    
    UITableViewPullToRefreshAssertMainThread();
    
    NDRefreshControl *view = [[NDRefreshControl alloc] init];
    view.frame = CGRectMake(0, -view.frame.size.height, CGRectGetWidth([UIScreen mainScreen].bounds), view.frame.size.height);
    
    view.scrollView = self;
    view.refreshActionHandler = [refreshActionHandler copy];
    [self addSubview:view];
    self.refreshControl = view;
}

- (void)nd_addPullToLoadMoreWithActionHandler:(void (^)(id sender))loadMoreActionHandler {
    UITableViewPullToRefreshAssertMainThread();
    
    NDRefreshControl *view = [[NDRefreshControl alloc] init];
    view.position = RefreshControlPositionBottom;
    view.frame = CGRectMake(0, CGRectGetHeight(self.bounds), CGRectGetWidth([UIScreen mainScreen].bounds), view.frame.size.height);
    NDRefreshLoadMoreContentView *containView = [[NDRefreshLoadMoreContentView alloc] init];
    containView.contentMode = UIViewContentModeScaleAspectFit;
    containView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    view.containView = containView;
    
    view.scrollView = self;
    view.refreshActionHandler = [loadMoreActionHandler copy];
    [self addSubview:view];
    self.loadMoreControl = view;
}

- (void)nd_beginRefreshing {
    [self.refreshControl beginRefreshing];
}

- (void)nd_endRefreshing {
    [self.refreshControl endRefreshing];
}

- (void)nd_beginLoadMore {
    [self.loadMoreControl beginRefreshing];
}

- (void)nd_endLoadMore {
    [self.loadMoreControl endRefreshing];
}
@end
